package com.mlethe.library.widget.wheelview.picker;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;

import androidx.annotation.IntRange;
import androidx.annotation.Nullable;

import com.mlethe.library.widget.wheelview.R;
import com.mlethe.library.widget.wheelview.WheelView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 小时 WheelView
 *
 * @author Mlethe
 * @version v1.0.0
 * @since 2018/8/20.
 */
public class HourWheelView extends WheelView<Integer> {

    private int mMaxHour = -1;
    private int mMinHour = -1;

    public HourWheelView(Context context) {
        this(context, null);
    }

    public HourWheelView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HourWheelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HourWheelView);
        int selectedHour = typedArray.getInt(R.styleable.HourWheelView_wvSelectedHour, Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
        typedArray.recycle();
        initData();
        if (selectedHour > 23){
            selectedHour = selectedHour % 24;
        }
        setSelectedHour(selectedHour);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        List<Integer> list = new ArrayList<>(1);
        for (int i = 0; i < 24; i++) {
            list.add(i);
        }
        super.setData(list);
    }

    public void setMaxHour(@IntRange(from = 0, to = 23) int maxHour) {
        mMaxHour = maxHour;
        checkCurrentSelected(getSelectedItemData());
    }

    public void setMinHour(@IntRange(from = 0, to = 23) int minHour) {
        mMinHour = minHour;
        checkCurrentSelected(getSelectedItemData());
    }

    /**
     * 获取选中的小时
     *
     * @return 选中的小时
     */
    public int getSelectedHour() {
        return getSelectedItemData();
    }

    /**
     * 设置选中的小时
     *
     * @param selectedHour 选中的小时
     */
    public void setSelectedHour(int selectedHour) {
        setSelectedHour(selectedHour, false);
    }

    /**
     * 设置选中的小时
     *
     * @param selectedHour   选中的小时
     * @param isSmoothScroll 是否平滑滚动
     */
    public void setSelectedHour(int selectedHour, boolean isSmoothScroll) {
        setSelectedHour(selectedHour, isSmoothScroll, 0);
    }

    /**
     * 设置选中的小时
     *
     * @param selectedHour   选中的小时
     * @param isSmoothScroll 是否平滑滚动
     * @param smoothDuration 平滑滚动持续时间
     */
    public void setSelectedHour(int selectedHour, boolean isSmoothScroll, int smoothDuration) {
        if (selectedHour >= 0 && selectedHour <= 23) {
            int shouldSelected = selectedHour;
            if (isMoreThanMaxHour(selectedHour)) {
                shouldSelected = mMaxHour;
            } else if (isLessThanMinHour(selectedHour)) {
                shouldSelected = mMinHour;
            }
            updateSelectedHour(shouldSelected, isSmoothScroll, smoothDuration);
        }
    }

    /**
     * 更新选中的小时
     *
     * @param selectedHour   选中的小时
     * @param isSmoothScroll 是否平滑滚动
     * @param smoothDuration 平滑滚动持续时间
     */
    private void updateSelectedHour(int selectedHour, boolean isSmoothScroll, int smoothDuration) {
        setSelectedItemPosition(selectedHour, isSmoothScroll, smoothDuration);
    }

    @Override
    public void setData(List<Integer> dataList) {
        throw new UnsupportedOperationException("You can not invoke setData method in " + HourWheelView.class.getSimpleName() + ".");
    }

    @Override
    protected void onItemSelected(Integer data, int position) {
        checkCurrentSelected(data);
    }

    private void checkCurrentSelected(int data) {
        if (isMoreThanMaxHour(data)) {
            setSelectedHour(mMaxHour);
        } else if (isLessThanMinHour(data)) {
            setSelectedHour(mMinHour);
        }
    }

    private boolean isMoreThanMaxHour(int data) {
        return data > mMaxHour && mMaxHour > 0;
    }

    private boolean isLessThanMinHour(int data) {
        return data < mMinHour && mMinHour > 0;
    }
}
